﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
namespace Dillon.CSV
{
    public class CSVReader : IDisposable
    {

        TextReader reader;
        private Errors errors;
        private ILexer lexer;
        readonly CSVReaderSettings settings;
        public CSVReader(string path)
            : this(path, Encoding.Default, CSVReaderSettings.Default)
        {

        }

        public CSVReader(TextReader reader)
            : this(reader, CSVReaderSettings.Default)
        {

        }

        public CSVReader(TextReader reader, CSVReaderSettings settings)
        {
            this.reader = reader;
            this.settings = settings;
            this.lexer = new CSVLexer(this.reader, settings);
            this.errors = this.lexer.Errors;
            this.lexer.MoveToNextToken();
        }

        public CSVReader(string path, Encoding encoding, CSVReaderSettings settings)
        {
            this.settings = settings;
            var fs = new FileStream(path, FileMode.Open, FileAccess.Read);
            this.reader = new StreamReader(fs, encoding);
            this.lexer = new CSVLexer(this.reader, settings);
            this.errors = this.lexer.Errors;
            this.lexer.MoveToNextToken();
        }

        public string[] Read()
        {

            if (this.EndOfStream)
            {
                return new string[0];
            }

            var rowValues = new List<string>();
            var isEmptyCell = true;

            while (true)
            {
                var nextToken = this.lexer.MoveToNextToken();
                var token = this.lexer.Token;

                if (token.Kind == Tokens.EOF)
                {
                    if (isEmptyCell)
                    {
                        rowValues.Add(string.Empty);
                    }
                    this.endOfStream = true;
                    break;
                }
                if (token.Kind == Tokens.RowSymbol)
                {
                    if (isEmptyCell)
                    {
                        rowValues.Add(string.Empty);
                    }
                    if (nextToken.Kind == Tokens.EOF)
                    {
                        this.endOfStream = true;
                    }
                    break;
                }
                else if (token.kind == Tokens.ColumnSymbol)
                {
                    if (isEmptyCell)
                    {
                        rowValues.Add(string.Empty);
                    }
                    isEmptyCell = true;
                    continue;

                }
                else
                {
                    isEmptyCell = false;
                    rowValues.Add(token.Value);
                }
            }
            return rowValues.ToArray();
        }

        private bool endOfStream;
        public bool EndOfStream
        {
            get
            {
                return this.endOfStream;
            }
        }

        public void Dispose()
        {
            this.reader.Dispose();
        }
    }


}
